{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Geodepy Tutorial: Angular Notation Formats\n",
    "\n",
    "This tutorial demonstrates GeodePy's system of functions and classes for handling angular notation. At the time of writing, Wikipedia lists 10 different units used to represent angles. This is too many, so GeodePy handles four (4) different kinds of notation commonly used in geodesy and surveying and this tutorial will show you how to convert between these. The four kinds of notation *(and their shorthand in code)* in GeodePy are:\n",
    "\n",
    "* Decimal Degrees *(dec)*\n",
    "* Degrees, Minutes and Seconds *(dms)*\n",
    "* Degrees and Decimal Minutes *(ddm)*\n",
    "* HP Notation *(hp)*\n",
    "    \n",
    "Let's start by importing the relevant functions from the `convert` module:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "from geodepy.convert import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python's `math` module also has two relevant functions, `degrees()` and `radians()`. These allow for conversion between **Decimal Degrees** and **Radians** and are used throughout GeodePy to perform calculations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.radians(57.29577951308232)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "57.29577951308232"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.degrees(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Decimal Degrees to Degrees, Minutes and Seconds\n",
    "\n",
    "We'll define a variable `dec_brad` as an angle in decimal degrees and store it as a float. To convert `dec_brad` from **Decimal Degrees** to **Degrees, Minutes and Seconds**, use the function `dec2dms()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DMSAngle: 57d 17m 44.80624709636322s}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dec_brad = 57.29577951308232\n",
    "dms_brad = dec2dms(brad)\n",
    "dms_brad"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Degrees, Minutes and Seconds notation uses a custom class called `DMSAngle`. Thus, we can get the **individual variables for degree, minute and second components separately:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "57"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dms_brad.degree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dms_brad.minute"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "44.80624709636322"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dms_brad.second"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Degrees, Minutes and Seconds to Degrees and Decimal Minutes\n",
    "\n",
    "To now convert this variable in **Degrees, Minutes and Seconds** to **Degrees and Decimal Minutes**, use the class method `.ddm()`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DDMAngle: 57d 17.746770784939386m}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ddm_brad = dms_brad.ddm()\n",
    "ddm_brad"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This can also be achieved using the function `dec2ddm` to convert **Decimal Degrees** to **Degrees and Decimal Minutes**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DDMAngle: 57d 17.746770784939386m}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dec2ddm(dec_brad)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### HP Notation\n",
    "\n",
    "The fourth notation type defined in GeodePy is HP Notation, and is named after the notation commonly used in HP Calculators. This takes the form `ddd.mmssssss` where `dd` is the degree component, `mm` the minute component and `ssssss` the second component (the first two `ss`s are the whole seconds and the remainder are the decimal places of seconds).\n",
    "\n",
    "To convert from **Degrees, Minutes and Seconds** to **HP Notation**, use the class method `.hp()`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DMSAngle: 57d 17m 44.80624709636322s}"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dms_brad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "57.17448062470964"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dms_brad.hp()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To convert from **HP Notation** to **Decimal Degrees**, use the function `hp2dec()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "57.295779513082316"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hp2dec(57.17448062470964)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Basic Logical and Arithmetic Operations\n",
    "\n",
    "All notation formats support logical operators (`==`, `!=`, `<=`, etc.) and basic arithmetic operations (`+`, `-`, `*`, etc.):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DMSAngle: 137d 33m 27.0s}"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DMSAngle(123,44,55) + DMSAngle(13,48,32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DMSAngle(13,30,45) == DDMAngle(13,30.75)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However as **HP Notation uses decimal float variables**, arithmetic operations using these will produce ordinary decimal arithmetic results. While this will work for some values in HP notation;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.43335"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1.12232 + 2.31103"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DMSAngle: 3d 43m 33.5s}"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DMSAngle(1,12,23.2) + DMSAngle(2,31,10.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "it will produce **incorrect results** for others:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "149.8762"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "124.3345 + 25.5417"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DMSAngle: 150d 28m 0.0s}"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DMSAngle(124,33,45) + DMSAngle(25,54,15)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Therefore, it is recommended that **all variables representing HP notation be converted to Decimal Degrees Notation before performing any calculations using `hp2dec()`**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{DMSAngle: 150d 28m 0.0s}"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dec2dms(hp2dec(124.3345) + hp2dec(25.5415))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
